/***This file will start the threads of each opened window game
    Copyright (C) 2012  Davide Moriello

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>. 
	
	Contact me for help or more info: davidemo89@gmail.com       ****/


#include <windows.h>
#include <fstream>
#include <iostream>
#include <cstring>
#include <list>
#include <process.h>
#include "settings.h"
#include "botlife.h"

using namespace std;


bool searchGameWindow(botlife& life, list<HWND> &windows,char*,char*);
bool getProcess(botlife&);
bool checkHandleExist(list<HWND> &windows);
void checkIfHandleIsRunning(list<HWND> &windows,list<HANDLE> &threads);
void getWindowSizeAndResize(list<HWND> &windows);
BOOL CALLBACK EnumChildProc(  __in  HWND hwnd,  __in  LPARAM lParam);

HWND _CHILDFOUND = NULL;

void findGameWindow(settings& sett)
{
	bool done = false;
	bool steam = false;
	char lpstr[80];		
	
	list<HWND> windows; //list of opened windows
	list<HANDLE> threads; //list of threads started
	list<HWND>::iterator iter; // Declare new iterator 

	

	while(!done)
	{
		HANDLE hThread;
		botlife life;		
		initProcess(life);

		checkIfHandleIsRunning(windows,threads); //Check if a thread is terminated if yes delete it from the list
		
		/**** HAVE TO WRITE ANOTHER SYSTEM TO CHECK THIS TWO TYPES OF WINDOW ***/
		life->gameProcess = FindWindow("ApolloRuntimeContentWindow","Realm of the Mad God"); //Steam version, no need to search Child
		if(life->gameProcess == NULL)
			life->gameProcess = FindWindow(NULL,"Adobe Flash Player 11"); //Flash Projector version, no need to search Child

		if(life->gameProcess != NULL){
			_CHILDFOUND = life->gameProcess;
			if(checkHandleExist(windows)){					
				windows.push_back(life->gameProcess);
				steam = true;					
			}else{
				getWindowSizeAndResize(windows);
				steam = false;
			}
			_CHILDFOUND = NULL;			
		}else{
			getWindowSizeAndResize(windows);
			steam = false;
		}


		if(!steam){		
			//START IF;
			if((searchGameWindow(life,windows,"MozillaWindowClass", "Realm of the Mad God - Mozilla Firefox")|| //Search on firefox normal
				searchGameWindow(life,windows,"MozillaWindowClass", "Play Realm of the Mad God, a free online game on Kongregate - Mozilla Firefox")|| //if no window on firefox normal found, check firefox on kongreate
				searchGameWindow(life,windows,NULL, "Realm of the Mad God - Google Chrome")|| //if nothing found search on chome
				searchGameWindow(life,windows,NULL, "Play Realm of the Mad God, a free online game on Kongregate - Google Chrome")|| //And so on...
				searchGameWindow(life,windows,NULL, "Realm of the Mad God - Windows Internet Explorer")|| //so on...
				searchGameWindow(life,windows,NULL, "Play Realm of the Mad God, a free online game on Kongregate - Windows Internet Explorer")|| //so on...
				searchGameWindow(life,windows,NULL, "Realm of the Mad God - Opera")|| //so on...
				searchGameWindow(life,windows,NULL, "Play Realm of the Mad God, a free online game on Kongregate - Opera")|| //so on...
				searchGameWindow(life,windows,"{1C03B488-D53B-4a81-97F8-754559640193}", "Realm of the Mad God"))|| //Oh, and this is the Safari versione
				searchGameWindow(life,windows,"{1C03B488-D53B-4a81-97F8-754559640193}", "Play Realm of the Mad God, a free online game on Kongregate"))//Safari on Kongregate
			{ 
				life->sett = sett; //Save settings in the life struct for pass the info in the thread
				/******************* START THREAD ***********************/
				/** THE FUNCTION checkLife IS IN THE FILE botlife.cpp **/
				threads.push_back(CreateThread(NULL,  0, (LPTHREAD_START_ROUTINE)checkLife, (LPVOID)life, 0, NULL ));				
					
			}
			//END IF;
			
		}else{			
			life->parentProcess = life->gameProcess;			
			life->sett = sett;
			/******************* START THREAD ***********************/
			/** THE FUNCTION checkLife IS IN THE FILE botlife.cpp **/
			threads.push_back(CreateThread(NULL,  0, (LPTHREAD_START_ROUTINE)checkLife, (LPVOID)life, 0, NULL ));
			cout << "Found game" << endl;			
		}
		//delete life;
		Sleep(5000);
	}
}

bool searchGameWindow(botlife& life, list<HWND> &windows,char* className, char* windowName){


	life->gameProcess = FindWindow((LPCSTR)className,(LPCSTR)windowName); //Search for window of the game
	if(life->gameProcess!= NULL){	//Search for child (flash object) in the browser
		EnumChildWindows(life->gameProcess,EnumChildProc,NULL);		
		life->parentProcess = life->gameProcess;
		
			if(checkHandleExist(windows)){
				life->gameProcess = _CHILDFOUND;
				setFocus(life);
				windows.push_back(life->gameProcess);
				cout << "game found on: " << windowName << endl;
				return true;
			}		

	}	
	return false;
}

bool checkHandleExist(list<HWND> &windows)
{
	list<HWND>::iterator iter; // Declare new iterator 

	for(iter = windows.begin(); iter != windows.end(); ++iter){ //check if the handle is open.				
		//cout << *iter << " - " << _CHILDFOUND << endl;
		if(*iter == _CHILDFOUND || _CHILDFOUND == NULL){
			return false;
		}
	}

	return true;

}

BOOL CALLBACK EnumChildProc(  __in  HWND hwnd,  __in  LPARAM lParam)
{
	char lpstr1[255];
	_CHILDFOUND = NULL;
	GetClassName(hwnd,lpstr1,80); 
	if(strcmp("MacromediaFlashPlayerActiveX",lpstr1) == 0 || strcmp("NativeWindowClass",lpstr1) == 0 || strcmp("MozillaWindowClass",lpstr1) == 0 || strcmp("aPluginWinClass",lpstr1) == 0 || strcmp("org.webkit.NetscapePluginWindow",lpstr1) == 0){
		_CHILDFOUND = hwnd;
		return false;
	}
	
	return true;
}

void getWindowSizeAndResize(list<HWND> &windows)
{
	list<HWND>::iterator iter;
	RECT rect;

	for(iter = windows.begin(); iter != windows.end();++iter){
		GetWindowRect(*iter,&rect);
		//cout << rect.right-rect.left << " - " << rect.bottom - rect.top << endl;
		if(rect.right-rect.left != 816 || rect.bottom - rect.top != 638){
			SetWindowPos(*iter,NULL,rect.left,rect.top,816,638,SWP_NOMOVE);
		}
	}
}


void checkIfHandleIsRunning(list<HWND> &windows,list<HANDLE> &threads)
{
	list<HWND>::iterator iter; // Declare new iterator for windows
	list<HANDLE>::iterator iter2; //Declare iterator for Threads
	DWORD ThreadStatus = 0;

	for(iter = windows.begin(),iter2 = threads.begin(); iter != windows.end();){			
		//cout << *iter << endl;
		if(GetExitCodeThread(*iter2,&ThreadStatus) != 0){
			if(ThreadStatus == 1){ //The thread dosent' exist anymore, so need to delete the items in the two list.
				//cout << "removed list" << endl;
				iter = windows.erase(iter);
				iter2 = threads.erase(iter2);
				ThreadStatus = 0; //Reset for security the status thread
			}else{
				++iter;
				++iter2;
			}
		}else{
			++iter;
			++iter2;
		}
	}
}